package com.my.ruyi.ssl;


import java.io.FileInputStream;
import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;

public class SslServer {
	static final int PORT = Integer.parseInt(System.getProperty("port", "9998"));
	
	public static void main(String[] args) throws Exception {
		// 1. 生成用于测试目的的临时自签名证书。
		// 注意：切勿使用此类在生产中生成的证书和私钥。 这纯粹是为了测试目的，因此它非常不安全。 
		// 它甚至使用一个不安全的伪随机发生器在内部进行快速生成。
		// 使用java.io.File.createTempFile（String，String）在系统的临时目录中生成X.509证书文件和RSA私钥文件，
		// 并在JVM退出时使用java.io.File.deleteOnExit（）。
		//SelfSignedCertificate certificate = new SelfSignedCertificate();
		//SslContext sslContext = SslContextBuilder.forServer(certificate.certificate(), certificate.privateKey()).build();
		
		// 2. 使用ssl证书的方式
		KeyManagerFactory keyManagerFactory = null;
		KeyStore keyStore = KeyStore.getInstance("JKS");
		// 密钥库和进入密钥库的密码
		keyStore.load(new FileInputStream("src/main/resources/serverChat.jks"), "654321".toCharArray());
		
		//keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
		keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		
		// 密钥库中 访问密钥的密码
		keyManagerFactory.init(keyStore, "123456".toCharArray());
		
		SslContext sslContext = SslContextBuilder.forServer(keyManagerFactory).build();
		
		NioEventLoopGroup boosGroup = new NioEventLoopGroup();
		NioEventLoopGroup workGroup = new NioEventLoopGroup();
		
		try {
			ServerBootstrap bootstrap = new ServerBootstrap();
			bootstrap.group(boosGroup, workGroup)
				.channel(NioServerSocketChannel.class)
				.handler(new LoggingHandler(LogLevel.INFO))
				.childHandler(new SslServerInitializer(sslContext));
			
			bootstrap.bind(PORT).sync().channel().closeFuture().sync();
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			boosGroup.shutdownGracefully();
			workGroup.shutdownGracefully();
		}
	}
}
